# encoding: utf-8

require 'rest-client'
require 'json'
require 'uri'

module Activiti
  class WyjatekKonektor < Exception; end
  class Konektor

    def initialize identyfikator_uzytkownika, haslo, url = "http://localhost:3030/activiti-rest/service/"
      @identyfikator_uzytkownika = identyfikator_uzytkownika.to_s
      @haslo                     = haslo.to_s
      @url = url
    end

    def wgraj_proces plik_procesu
      begin
        raise "Nie istenie taki plik #{plik_procesu}" unless File.exists? plik_procesu
        plik =  File.new( plik_procesu )
        przygotowany_adres = przygotuj_adres "deployment"
        wlasciwy_url  = ustaw_uzytkownika_dla_url przygotowany_adres
        RestClient.post wlasciwy_url, :upload => { :file => plik }
      rescue Exception => ex
        raise "Nie udało sie wgrać pliku procesu, powod #{ex.message}"
      end
    end
    def podaj_uzytkownika uzytkownik_id = @identyfikator_uzytkownika
      begin
        adres = przygotuj_adres "user/#{uzytkownik_id}"
        json_get adres
      rescue Exception => ex
        raise "Nie udało sie porbać uzytkownika o id: #{uzytkownik_id}, upewnij się ze taki użtykownik istnieje"
      end
    end
    def podaj_grupy_uzytkownika
      adres = przygotuj_adres "user/#{@identyfikator_uzytkownika}/groups"
      json_get adres
    end

    def podaj_definicje_procesow
      begin
        adres = przygotuj_adres "process-definitions"
        json_get adres
      rescue Exception => ex
        raise "Nie udało sie pobrać definicji procesów, powod: #{ex.message}"
      end
    end
    def podaj_instancje_procesow
      begin
        adres = przygotuj_adres "process-instances"
        json_get adres
      rescue Exception => ex
        raise "Nie udało sie pobrać instancji procesów, powod: #{ex.message}"
      end
    end
    def loguj
      begin
        adres  = przygotuj_adres "login"
        dane = { :userId => @identyfikator_uzytkownika, :password => "" }
        json_post adres, dane
      rescue Exception => ex
        raise "Nie udało sie zalogować, upewnij sie że użytkownik o id #{@identyfikator_uzytkownika} istenieje"
      end
    end
    def startuj_proces proc_def_key, zmienne = {}
      begin
        adres = przygotuj_adres 'process-instance'
        dane = { "processDefinitionKey" =>  proc_def_key }
        dane.merge! zmienne
        json_post adres, dane
      rescue Exception => ex
        raise "Nie udało sięwystartować procesu o kluczy #{proc_def_key}, przez użtykownika #{@identyfikator_uzytkownika} - sprawdz logi Activti Rest"
      end
    end
    def podaj_zadania_przypisane
      begin
        adres  = przygotuj_adres "tasks?&assignee=#{@identyfikator_uzytkownika}"
        puts adres
        json_get adres
      rescue Exception => ex
        raise "Nie udało sie pobrać zadań przypisanych do użtykownika #{@identyfikator_uzytkownika} - sprawdz logi Activiti Rest, powodw: #{ex.message}"
      end
    end
    def podaj_zadania_do_podjecia
      begin
        adres  = przygotuj_adres "tasks?&candidate=#{@identyfikator_uzytkownika}"
        puts adres
        json_get adres
      rescue Exception => ex
        raise "Nie udało sie pobrać zadań do podjęcia dla  użtykownika #{@identyfikator_uzytkownika} - sprawdz logi Activiti Rest, powodw: #{ex.message}"
      end
    end
    def podaj_zadania_podsumowanie
      begin
        adres  = przygotuj_adres "tasks-summary?user=#{@identyfikator_uzytkownika}"
        json_get adres
      rescue Exception => ex 
        raise "Nie udało sie pobrać podsumowania zadan dla uyztkownika #{@identyfikator_uzytkownika} - sprawdz logi Activiti Rest"
      end
    end
    def podaj_zadanie zadanie_id
      begin
        przygotowany_adres  = przygotuj_adres "task/#{@zadanie_id}"
        json_get adres
      rescue Exception => ex
        raise "Nie udało sie pobrać zadania o identyfikatorze #{@zadanie_id} - sprawdz logi Activiti Rest"
      end
    end
    def zwroc_zadanie_do_puli zadanie_id
      begin
        adres = przygotuj_adres "task/#{zadanie_id}/unclaim"
        json_put adres
      rescue Exception => ex
        raise "Nie udało sie zwrócic zadania do puli zadana do podjęcia - sprawdz logi Activiti Rest"
      end
    end
    def podejmij_zadanie zadanie_id
      begin
      adres = przygotuj_adres "task/#{zadanie_id}/claim"
      json_put adres
      rescue Exception => ex
        raise "Nie udało się podjąc zadania o id #{zadanie_id} dla uzytkownika od identifikatorze #{@identyfikator_uzytkownika} - sprawdz logi Activiti Rest"
      end
    end
    def przypisz_zadanie zadanie_id, komu
      begin
        adres = przygotuj_adres "task/#{zadanie_id}/assign"
        dane = { :userId => komu }
        json_put adres, dane
      rescue Exception => ex
        raise "Nie udało się przypisać zadania o id #{zadanie_id} dla uzytkownika od identifikatorze #{komu} - sprawdz logi Activiti Rest"
      end
    end
    def wykonaj_zadanie zadanie_id, zmienne = {}
      begin
        adres = przygotuj_adres "task/#{zadanie_id}/complete"
        json_post adres, zmienne
      rescue Exception => ex
        raise "Nie udało się wykonać zadania o id #{zadanie_id}, dla zmiennych #{zmienne} - sprawdz logi Activiti Rest"
      end
    end
    def podaj_diagram_instacji id_procesu
      begin
        adres = przygotuj_adres "process-instance/#{id_procesu}/diagram"
        get_post adres
      rescue Exception => ex
        raise "Nie udało się pobrać diagramu dla instancji #{id_procesu}, powod: #{ex.message} - sprawdz logi Activiti Rest"
      end
    end

    def podaj_diagram_definicji id_definicji
      begin
        adres = przygotuj_adres "process-definition/#{id_definicji}/diagram"
        json_get adres
      rescue Exception => ex
        raise "Nie udało się pobrać diagramu dla definicji procesu, powod: #{ex.message} - sprawdz logi Activiti Rest"
      end
    end

    private
    def json_get url
      begin
        RestClient.get url
      rescue Exception => ex
        raise WyjatekKonektor.new( "Nie udało się wykonać rządania JSON-GET dla #{url}, powod: #{ex.message}" )
      end
    end
    def post url, zmienne
    end
    def json_put url, zmienne = {}
      begin
        RestClient.post url, zmienne.to_json, { :content_type => :json }
      rescue Exception => ex
        raise WyjatekKonektor.new( "Nie udało się wykonać rządania JSON-PUT dla #{url}, z zmiennymi: #{zmienne}, powod: #{ex.message}" )
      end
    end
    def json_post url, zmienne = {}
      begin
        RestClient.post url, zmienne.to_json, { :content_type => :json }
      rescue Exception => ex
        raise WyjatekKonektor.new( "Nie udało się wykonać rządania JSON-POST dla #{url}, z zmiennymi: #{zmienne}, powod: #{ex.message}" )
      end
    end
    def ustaw_uzytkownika uri
      uri.user = @identyfikator_uzytkownika
      uri.password = @haslo
      return uri
    end
    def przygotuj_adres koncowka
      url =  @url + koncowka
      uri = URI.parse( url )
      uri = ustaw_uzytkownika uri
      uri.to_s
    end
  end
end
